import os
import re
import json
import time
import requests
from urllib.parse import unquote, urlencode
from fake_useragent import UserAgent

# 创建保存图片的文件夹
os.makedirs('baidu_images', exist_ok=True)

# 随机生成浏览器User-Agent
ua = UserAgent()

headers = {
    'User-Agent': ua.random,
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
    'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8',
    'Connection': 'keep-alive',
    'Referer': 'https://image.baidu.com/',
    'Upgrade-Insecure-Requests': '1',
    'Sec-Fetch-Dest': 'document',
    'Sec-Fetch-Mode': 'navigate',
    'Sec-Fetch-Site': 'same-origin',
    'Sec-Fetch-User': '?1',
}


def get_baidu_cookies():
    """获取必要的百度cookies"""
    session = requests.Session()
    session.get('https://www.baidu.com', headers=headers)
    return session.cookies.get_dict()


def download_images(keyword, page_nums = 1, page_size = 30):
    """下载百度图片搜索结果"""
    base_url = "https://image.baidu.com/search/acjson"

    for page in range(1, page_nums + 1):

        pn = (page - 1) * page_size
        gsm = hex(pn + page_size)[2:]  # 计算gsm值

        # 构建查询参数
        params = {
            'tn': 'resultjson_com',
            'logid': '',
            'ipn': 'rj',
            'ct': 201326592,
            'is': '',
            'fp': 'result',
            'cl': 2,
            'lm': -1,
            'ie': 'utf-8',
            'oe': 'utf-8',
            'adpicid': '',
            'st': -1,
            'z': '',
            'ic': 0,
            'hd': 0,
            'latest': 0,
            'copyright': 0,
            'word': keyword,
            's': '',
            'se': '',
            'tab': '',
            'width': '',
            'height': '',
            'face': 0,
            'istype': 2,
            'qc': '',
            'nc': 1,
            'fr': '',
            'expermode': '',
            'force': '',
            'pn': pn,  # 起始图片索引
            'rn': page_size,  # 每页数量
            'gsm': gsm,
            '1688812345678': int(time.time() * 1000)  # 时间戳参数
        }

        # 获取初始cookies
        cookies = get_baidu_cookies()

        try:
            response = requests.get(
                base_url,
                headers=headers,
                params=params,
                cookies=cookies,
                timeout=10
            )
            response.raise_for_status()

            # 处理特殊JSON格式
            json_str = response.text.replace(r"\'", "'")
            data = json.loads(json_str)

            # 提取图片数据
            image_items = data.get('data', [])[:-1]  # 排除最后一个空元素

            if not image_items:
                print("未获取到图片数据，请检查反爬虫策略")
                return

            # 下载图片
            for idx, item in enumerate(image_items):
                img_url = item.get('thumbURL') or item.get('middleURL')
                print(img_url)

                # img_url = item.get('objURL') or item.get('replaceUrl', [{}])[0].get('ObjURL')
                if not img_url:
                    continue

                try:
                    # 下载图片
                    img_data = requests.get(
                        img_url,
                        headers={
                            'User-Agent': ua.random,
                            'Referer': 'https://image.baidu.com/'
                        },
                        timeout=8
                    ).content

                    # 生成文件名
                    filename = str(page) + '-' + str(idx) + '、' + unquote(img_url.split('/')[-1].split('?')[0])
                    filepath = f"baidu_images/{filename}.jpg"

                    # 保存图片
                    with open(filepath, 'wb') as f:
                        f.write(img_data)

                    print(f"已下载 {idx + 1}/{len(image_items)}: {filename}")
                    time.sleep(0.5)  # 添加延迟避免过快请求

                except Exception as e:
                    print(f"下载失败 [{img_url}]: {str(e)}")

        except Exception as e:
            print(f"请求失败: {str(e)}")



if __name__ == "__main__":
    keyword = "室内图"  # 搜索关键词
    download_images(keyword, 2,60)
    print("图片下载完成！保存至 baidu_images/ 文件夹")